<template>
	<view class="box flex-column" :class="[border?'border':'']">
		<text class="mb10" v-if="label">
			<text>{{label}}</text>
			<text class="base-color"  @click="descClick">{{labeldesc}}</text>
		</text>
		<view class="upload-box flex-row-center">
			<view class="item flex-center flex-column" v-for="(v,i) in files" :key="i">
				<!-- img 非直传oss -->
				<image class="file-img" v-if="type==='img'||['jpg','png','jpeg'].includes(v.url.split('.')[1])" :src="`${v.dir=='upload'?$c.serverHost:$c.serverHost}${v.dir}/${v.url}`" mode="aspectFill" @tap.stop="$c.previewImage(`${v.dir=='upload'?$c.serverHost:$c.serverHost}${v.dir}/${v.url}`)"></image>
				<!-- 视频 直传oss -->
				<video v-else-if="type==='video'||['mp4','avi','mov'].includes(v.url.split('.')[1])" :src="`${$c.serverHost}upload/${v.url}`"></video>
				
				<view class="del-box flex-center" v-if="isDelete" @tap="updata(i)">
					<image class="del-icon flex-center" :src="`/static/${icontype=='del'?'2':'3'}.png`" mode="aspectFill"></image>
				</view>
			</view>
			<view class="upload-icon flex-center" v-if="count>files.length" @tap="choose(null)"><image class="icon" src="/static/1.png" mode="aspectFill"></image></view>
		</view>
	</view>
</template>

<script>
	export default {
		name:"my-form-upload",
		emits: ['update:modelValue','uploadsuccess'],
		props:{
			modelValue: {
				type: [String,Array],
				default: function(){
					return []
				}
			},
			// img/video/other
			type: {
				type: String,
				default: function(){
					return 'img'
				}
			},
			label: {
				type: String,
				default: function(){
					return ''
				}
			},
			labeldesc: {
				type: String,
				default: function(){
					return ''
				}
			},
			dir: {
				type: String,
				default: function(){
					return ''
				}
			},
			border: {
				type: Boolean,
				default: function(){
					return false
				}
			},
			count: {
				type: Number,
				default: function(){
					return 9
				}
			},
			isDelete: {
				type: Boolean,
				default: function(){
					return true
				}
			},
			icontype: {
				type: String,
				default: function(){
					return 'del'
				}
			},
			isAliOss: {
				type: Boolean,
				default: function(){
					return false//仅仅针对视频 暂时弃用 视频都直传oss
				}
			},
			maxW: {
				type: Number,
				default: function(){
					return 450
				}
			},
		},
		data() {
			return {
				ispreFiles: '',
				files: [],
				isShow: false,
				updataIdx: null,
				option: {}
			};
		},
		mounted() {
			this.init()
		},
		watch: {
			modelValue(val){
				if(this.isShow){
					this.setvalue()
				}else{
					this.isShow = true
					this.init()
				}
			},
		},
		methods: {
			async init(){
				this.files = []
				if(this.modelValue){
					let values = typeof this.modelValue ==='string' ? this.modelValue.split(',') : this.modelValue
					this.ispreFiles = values.join(',')
					values.forEach(e=>{
						let o = {
							url: e,
							dir: this.dir
						}
						this.files.push(o)
					})
				}
				if(this.isAliOss){
					this.option =  await this.getTst()
				}
			},
			setvalue(){
				if(this.modelValue){
					let values = typeof this.modelValue ==='string' ? this.modelValue.split(',') : this.modelValue
					let files = []
					values.forEach(e=>{
						let isPre = this.ispreFiles.indexOf(e)
						let o = {
							url: e,
							dir: isPre!==-1?this.dir:'upload'
						}
						files.push(o)
					})
					this.files = files
				}
			},
			choose(i){
				let chooseImage=()=>{
					uni.chooseImage({
						sourceType: ['camera', 'album'],
						count: this.count - this.files.length,
						extension:['.png','.jpg','.jpeg'],
						success: (e) => {
							console.log(e)
							let imgs = e.tempFilePaths;
							this.uploads(imgs,this.maxW,false)
						}
					})
				}
				let chooseVideo=()=>{
					uni.chooseVideo({
						sourceType: ['camera', 'album'],
						extension:['.mp4','.mov','.avi'],
						success: (e)=> {
							if(e.tempFilePath){
							console.log(e)
								let videos = [e.tempFilePath];
								this.uploads(videos,this.maxW,true)
							}
						}
					})
				}
				this.updataIdx = i
				if(this.type==='all'){
					uni.showActionSheet({
						itemList: ['图片', '视频'],
						success: (res)=>{
							if(res.tapIndex==0){
								chooseImage()
							}else{
								chooseVideo()
							}
						},
						fail: function (res) {console.log(res.errMsg);}
					});
				}else if(this.type==='img'){
					chooseImage()
				}else if(this.type==='video'){
					chooseVideo()
				}
			},
			//获取上传配置
			getTst(){
				return new Promise((res,rej)=>{
					this.$reQuest.post('ding/sts',{},{token: true},).then(d=>{
						if(d.success&&d.msg){
							res(JSON.parse(d.msg))
						}else{res(null)}
					}).catch(err=>{res(null)})
				})
			},
			async uploads(files,w=2000,isAliOss){
				if(files.length<=0){
					// uni.showToast({
					// 	title: '上传成功',
					// 	icon: 'none'
					// })
					 return
				}
				//上传视频
				if(isAliOss){
					if(this.option){
						AliOss.upload(files[0],this.type=='img'?'jpg':'mp4',this.option,(rs)=> {
							if(rs.code===1){
								// this.$c.Toast('上传成功！')
								let reg = new RegExp("upload/","g");
								let filename = rs.file.replace(reg,"")
								files.splice(0,1)
								this.uploadsuccess(filename)
								this.uploads(files,w,isAliOss)
							}
							if(rs.code===0){
								files.splice(0,1)
								this.uploads(files,w,isAliOss)
								this.$c.Toast('上传失败！');
							}
							// if(rs.code===2){//上传中
							// 	this.progress = rs.progress
							// }
						})
					}else{
						this.option = await this.getTst()
						this.$c.Toast('获取OSS服务失败，现无法上传，请稍后再试！');
					}
				}else{//上传图片
					const uploadTask = uni.uploadFile({
						// 需要上传的地址
						url: this.$c.uploadHost,
						// 需要上传的文件
						filePath: files[0],
						header: {
							'token': this.$c.getToken()
						},
						name: 'file',
						formData: {
							'maxwidth': 1200,
							'maxheight': 1600,
							'rename': 1
						},
						success: res1 => {
							let data = JSON.parse(res1.data)
							if(data.success){
								files.splice(0,1)
								this.uploadsuccess(data.filename)
								this.uploads(files,w,isAliOss)
							}else{
								files.splice(0,1)
								this.uploads(files,w,isAliOss)
								this.$c.Toast('上传失败！');
							}
							
						},
						fail: err => {
							uni.showToast({
								title: JSON.stringify(err),
								icon: 'none'
							})
						}
					});
					// 监听进度
					uploadTask.onProgressUpdate(res => {
						// this.progress = res.progress
						// if (res.progress == 100) {
						// 	this.progress = 0
						// }
					});
				}
			},
			uploadsuccess(e){
				let arr = []
				let files = []
				if(this.icontype=='updata'&&this.updataIdx!==null){
					this.files.forEach((ev,i)=>{
						files.push(this.updataIdx==i?e:ev.url)
					})
				}else{
					this.files.forEach((ev,i)=>{
						arr.push(ev.url)
					})
					files = arr.concat([e])
				}
				this.isShow = true
				this.$emit('update:modelValue',files.join(','))
				this.$emit('uploadsuccess',files.join(','))
			},
			updata(i){
				if(this.icontype=='updata'){
					this.choose(i)
					return
				}
				let files = []
				this.files.splice(i,1)
				this.files.forEach(ev=>{
					files.push(ev.url)
				})
				this.$emit('update:modelValue',files.join(','))
				this.$emit('uploadsuccess',files.join(','))
			},
			descClick(){
				this.$emit('descclick')
			}
		}
	}
</script>

<style lang="scss">
	.box{
		font-size: 28rpx;
		width: 100%;
		.upload-box{
			flex-wrap: wrap;
			.upload-icon{
				width: 120px; height: 120px; border-radius: 10rpx; background-color: #f0f0f0; margin: 0 10rpx 10rpx 0;
				.icon{
					width: 30px; height: 30px;
				}
			}
			.item{
				position: relative;
				width: 120px; height: 120px; border-radius: 10rpx; background-color: #f0f0f0; margin: 0 10rpx 10rpx 0; 
				overflow: hidden;
				.file-img{
					width: 120px; height: 120px; border-radius: 10rpx;
				}
				.del-box{
					position: absolute; right: 8rpx; top: 8rpx; z-index: 10; background: rgba(0, 0, 0, 0.6); border-radius: 24px;
					width: 22px; height: 22px;
					 // background: rgba(255,255,255,0.3);
					.del-icon{
						width: 14px; height: 14px;
					}
				}
			}
		}
	}
	.border{
		border-bottom: solid 1rpx #f0f0f0; box-sizing: border-box;
	}
</style>